package com.software.audiorecorddemo

import android.media.MediaCodec
import android.media.MediaCodecInfo
import android.media.MediaFormat
import android.util.Log
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.nio.ByteBuffer

/**
 * 音频处理工具类
 * 负责PCM到AAC的转换等音频处理功能
 */
class AudioProcessor {
    companion object {
        private const val TAG = "AudioProcessor"
        
        /**
         * PCM文件转AAC文件
         */
        fun pcmToAac(
            pcmFile: File,
            aacFile: File,
            sampleRate: Int,
            channels: Int,
            bitRate: Int = 96000 // 默认比特率96kbps
        ): Boolean {
            if (!pcmFile.exists()) {
                Log.e(TAG, "PCM文件不存在: ${pcmFile.absolutePath}")
                return false
            }
            
            // 确保目标文件夹存在
            aacFile.parentFile?.mkdirs()
            
            // 如果AAC文件已存在，则删除
            if (aacFile.exists()) {
                aacFile.delete()
            }
            
            var mediaCodec: MediaCodec? = null
            var inputStream: FileInputStream? = null
            var outputStream: FileOutputStream? = null
            
            try {
                // 配置AAC编码格式
                val format = MediaFormat.createAudioFormat(
                    MediaFormat.MIMETYPE_AUDIO_AAC,
                    sampleRate,
                    channels
                )
                
                // 设置比特率
                format.setInteger(MediaFormat.KEY_BIT_RATE, bitRate)
                format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC)
                format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 16384)
                
                // 创建编码器
                mediaCodec = MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_AUDIO_AAC)
                mediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE)
                mediaCodec.start()
                
                // 创建输入输出流
                inputStream = FileInputStream(pcmFile)
                outputStream = FileOutputStream(aacFile)
                
                // 读取PCM数据
                val inputBuffer = ByteArray(16384)
                val bufferInfo = MediaCodec.BufferInfo()
                
                // 读取超时
                val TIMEOUT_US = 10000L
                var inputDone = false
                var outputDone = false
                
                // 整个编码过程
                while (!outputDone) {
                    // 处理输入
                    if (!inputDone) {
                        val inputBufferId = mediaCodec.dequeueInputBuffer(TIMEOUT_US)
                        if (inputBufferId >= 0) {
                            val codecInputBuffer = mediaCodec.getInputBuffer(inputBufferId)
                            codecInputBuffer?.clear()
                            
                            // 从PCM文件读取数据
                            val bytesRead = inputStream.read(inputBuffer)
                            
                            if (bytesRead < 0) {
                                // 文件读取结束
                                mediaCodec.queueInputBuffer(
                                    inputBufferId,
                                    0,
                                    0,
                                    System.nanoTime() / 1000,
                                    MediaCodec.BUFFER_FLAG_END_OF_STREAM
                                )
                                inputDone = true
                                Log.d(TAG, "PCM数据读取完毕")
                            } else {
                                // 将数据写入编码器
                                codecInputBuffer?.put(inputBuffer, 0, bytesRead)
                                mediaCodec.queueInputBuffer(
                                    inputBufferId,
                                    0,
                                    bytesRead,
                                    System.nanoTime() / 1000,
                                    0
                                )
                            }
                        }
                    }
                    
                    // 处理输出
                    val outputBufferId = mediaCodec.dequeueOutputBuffer(bufferInfo, TIMEOUT_US)
                    if (outputBufferId >= 0) {
                        // 判断是否结束
                        if ((bufferInfo.flags and MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                            outputDone = true
                        }
                        
                        // 处理有效数据
                        if (bufferInfo.size > 0) {
                            val outputBuffer = mediaCodec.getOutputBuffer(outputBufferId)
                            outputBuffer?.position(bufferInfo.offset)
                            outputBuffer?.limit(bufferInfo.offset + bufferInfo.size)
                            
                            // 从编码器读取AAC数据并添加ADTS头
                            val outData = ByteArray(bufferInfo.size + 7) // 7字节的ADTS头
                            
                            // 创建ADTS头
                            addADTStoPacket(outData, bufferInfo.size + 7, sampleRate, channels)
                            
                            // 将AAC数据拷贝到outData中
                            outputBuffer?.get(outData, 7, bufferInfo.size)
                            outputBuffer?.position(bufferInfo.offset)
                            
                            // 写入到文件
                            outputStream.write(outData)
                            
                            // 释放输出缓冲区
                            mediaCodec.releaseOutputBuffer(outputBufferId, false)
                        }
                    } else if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                        // 输出格式已更改，通常在编码开始时发生一次
                        Log.d(TAG, "输出格式已更改: ${mediaCodec.outputFormat}")
                    }
                }
                
                // 编码完成
                Log.d(TAG, "AAC编码完成: ${aacFile.absolutePath}")
                return true
                
            } catch (e: Exception) {
                Log.e(TAG, "AAC编码失败: ${e.message}", e)
                return false
            } finally {
                // 释放资源
                try {
                    mediaCodec?.stop()
                    mediaCodec?.release()
                    inputStream?.close()
                    outputStream?.close()
                } catch (e: Exception) {
                    Log.e(TAG, "释放资源失败: ${e.message}")
                }
            }
        }
        
        /**
         * 添加ADTS头到AAC包
         * ADTS: Audio Data Transport Stream
         */
        private fun addADTStoPacket(packet: ByteArray, packetLen: Int, sampleRate: Int, channels: Int) {
            // ADTS头信息
            val profile = 2  // AAC LC
            val freqIdx = getFrequencyIndex(sampleRate)
            val chanCfg = channels  // 声道数
            
            // 填充ADTS头
            packet[0] = 0xFF.toByte()  // 同步字
            packet[1] = 0xF9.toByte()  // 同步字 + 版本 + 层 + 保护缺失位
            packet[2] = (((profile - 1) shl 6) + (freqIdx shl 2) + (chanCfg shr 2)).toByte()
            packet[3] = (((chanCfg and 3) shl 6) + (packetLen shr 11)).toByte()
            packet[4] = ((packetLen and 0x7FF) shr 3).toByte()
            packet[5] = (((packetLen and 7) shl 5) + 0x1F).toByte()
            packet[6] = 0xFC.toByte()  // 全为1 + 帧数 (此处设置为单帧)
        }
        
        /**
         * 获取采样率索引值
         */
        private fun getFrequencyIndex(frequency: Int): Int {
            return when (frequency) {
                96000 -> 0
                88200 -> 1
                64000 -> 2
                48000 -> 3
                44100 -> 4
                32000 -> 5
                24000 -> 6
                22050 -> 7
                16000 -> 8
                12000 -> 9
                11025 -> 10
                8000 -> 11
                7350 -> 12
                else -> 4 // 默认44.1kHz
            }
        }
    }
} 